<template>
  <div class="h-layout__main">
    <!-- 云台 -->
    <camera-control
      :camera-key="cameraKey"
      :play-mode="playMode"
      :position="{left: 0, bottom: 0}"
    />
    <div class="h-layout__left">
      <!-- 摄像头列表 -->
      <layout-tree
        ref="tree"
        :node-key="treeNodeKey"
        search-key="name"
        :data="cameraList"
        :show-search="true"
        :show-checkbox="true"
        :props="treeOptions"
        :default-expand-all="true"
        @current-change="currentNodeChange"
        @check-change="checkChange"
        @get-replay-date="getReplayDate"
      />
    </div>
    <div class="h-layout__right">
      <!-- 布局 -->
      <video-layout
        :camera-key="cameraKey"
        :server="server"
        :user-info="userInfo"
        :enable-h-t-t-p-s="enableHTTPS"
        :play-mode="playMode"
        :snap-dir="snapDir"
        :video-dir="videoDir"
        :button-ids="buttonIds"
        :layout="layout"
        :reconnect-duration="reconnectDuration"
        :reconnect-times="reconnectTimes"
        :show-smart="showSmart"
        :show-toolbar="showToolbar"
        :smart-list="smartList"
      />
    </div>
  </div>
</template>

<script>
import axios from 'axios'
import { defaultState } from './mixins'
import CameraControl from './components/control'
import LayoutTree from './components/tree'
import VideoLayout from './components/layout'

export default {
  name: 'VideoManagement',
  components: {
    CameraControl,
    LayoutTree,
    VideoLayout
  },
  mixins: [defaultState],
  props: {
    userInfo: {
      type: Object,
      default: () => {
        return {
          name: 'test',
          password: '13D2741B4175948BFDD8807B055610C3'
        }
      }
    },
    cameraKey: {
      type: String,
      default: 'ChanPubId'
    },
    // 是否启用 HTTPS 协议与平台交互 非必填
    enableHTTPS: {
      type: Boolean,
      default: false
    },
    // 指定模式的布局 初始播放模式 0-预览 1-回放 默认为0
    playMode: {
      type: Number,
      default: 0
    },
    // 抓图存储路径 非必填
    snapDir: {
      type: String,
      default: ''
    },
    // 紧急录像或录像剪辑存储路径 非必填
    videoDir: {
      type: String,
      default: ''
    },
    /*
      如未指定或指定值无效，使用默认值“2x2”布局，
      可选值有如未指定或指定值无效，使用默认值“2x2”布局，
      可选值有“1x1”、“1x2”、“2x2”、“3x3”、“4x4”、“5x5”、“1+2”、“1+5”、“1+7”、“1+8”、“1+9” 、“1+12” 、“1+16” 、“4+9” 、“1+1+12”、“3+4”、“1x4”、“4x6”
      1*1/1*2/2*2/3*3/4*4//1*4-----1+2/  1+5/ 1+7/1+8/1+9//3+4  4+9/1+1+12  1+12/
     */
    layout: {
      type: String,
      default: '3*3'
    },
    /*
      是否显示工具栏
      不指定或指定字段值为非 0，则默认显示，
      如指定字段值为 0，则不显示
      播放bottom-bar
     */
    showToolbar: {
      type: Boolean,
      default: true
    },
    /*
      是否显示智能信息
      不指定或指定字段值为非 0，则默认显示，如指定字段值为 0，则不显示。
      目前支持的智能信息有智能分析信息、移动侦测信息、POS 信息后叠加信息、图片叠加信息、热成像信息、温度信息的开关配置
     */
    showSmart: {
      type: Boolean,
      default: false
    },
    smartList: {
      type: Array,
      default: () => []
    },
    // 工具条按钮字符串，多个之间以“,”分割
    buttonIds: {
      type: String,
      default: '1,2,3,5,6'
    },
    /*
      重连次数
      0-无限重连 >0-重连次数 <0-不重连，不填则默认值为 0-无限重连
     */
    reconnectTimes: {
      type: Number,
      default: 3
    },
    /*
      重连间隔时间
      取值 1~10 秒，如超出最小或最大值， 以最小或最大值为准。不填默认重连间隔时间 5 秒
     */
    reconnectDuration: {
      type: Number,
      default: 5
    },
    // 请求地址
    server: {
      type: Object,
      default: () => {
        return {
          // websocket
          ws: {
            // ip: '140.249.20.46',
            ip: '192.168.15.230',
            port: '5678'
          },
          // 视频相关地址
          stream: {
            // ip: '140.249.20.46',
            ip: '192.168.15.230',
            port: '8687'
          },
          // 用户登录及摄像头获取
          api: {
            // ip: '140.249.20.46',
            ip: '192.168.15.230',
            port: '8686'
          },
          // 内网穿透，视频流交互
          iceServer: {
            'url': 'turn:140.249.20.46:3478',
            'username': 'testturn',
            'credential': 'testturn'
          }
        }
      }
    }
  },
  data() {
    return {
      cameraList: [],
      treeOptions: {
        label: 'name',
        children: 'children'
      },
      url: '',
      loginTimer: null,
      aliveTime: 60
    }
  },
  watch: {
    videoLayoutList: {
      handler: function(val, oldVal) {
        const list = val.filter(item => {
          return item.cameraInfo[this.treeNodeKey] !== ''
        })
        this.filterPlay(this.cameraList, list)
        const cameraList = this.getNewData(this.cameraList)
        this.$set(this.$data, 'cameraList', cameraList)
      },
      deep: true
    }
  },
  created() {
    this.changeLayoutConfig(this.$props)
    this.login()
  },
  methods: {
    // 创建连接
    login() {
      this.url = `${this.layoutConfig.enableHTTPS ? 'https://' : 'http://'}${this.server.api.ip}:${this.server.api.port}`
      axios.get(`${this.url}/ivms/login?UsrName=${this.userInfo.name}&Passwd=${this.userInfo.password}`).then(res => {
        if (res.status === 200 && res.data['AuthorizationId']) {
          this.changeAuthorizationId(res.data['AuthorizationId'])
          this.keepAlive()
          axios.get(`${this.url}/ivms/get_usr_all_resources?start=1&limit=100&AuthorizationId=${res.data['AuthorizationId']}`).then(r => {
            if (r.status === 200) {
              this.cameraList = this.formatTree(r.data['Resource'], 'ChanPubId', 'BindGroupPubId')
              this.formatName(this.cameraList)
            }
          })
        } else {
          this.$message.warning(res.data['errdesc'])
        }
      })
    },
    keepAlive() {
      if (!this.loginTimer && this.authorizationId) {
        this.loginTimer = setInterval(() => {
          axios.get(`${this.url}/ivms/keeplive?AuthorizationId=${this.authorizationId}`).then(res => {
            if (res.data.errcode === 0) {
              if (this.aliveTime !== res.data.Keeplive) {
                this.aliveTime = res.data.Keeplive
                clearInterval(this.loginTimer)
                this.loginTimer = null
                this.keepAlive()
              }
            } else {
              this.$message.error(res.data.errdesc)
            }
          }).catch(err => {
            console.log(err)
            this.$message.error('保活失败！请联系管理员')
            clearInterval(this.loginTimer)
            this.loginTimer = null
          })
        }, this.aliveTime * 1000 / 2)
      } else {
        this.aliveTime = 60
        this.login()
      }
    },
    formatName(list) {
      list.map(item => {
        if (item.children) {
          item.name = `${item.name}(0/${item.children.length})`
          item.icon = 'el-icon-folder-opened'
          item.disabled = false
          this.formatName(item.children)
        } else {
          item.icon = 'el-icon-camera'
          item.disabled = !item.online
        }
        return item
      })
    },
    formatTree(data, id, parentId) {
      if (data.length) {
        const map = {}
        const val = []
        // 生成数据对象集合
        data.forEach(it => {
          it.name = ((it['NickName'] === it[id] ? it['SerialNumber'] : it['NickName']) || 'null')
          it.online = it.DevType !== -1 && it.Alive === 1
          // + (it.DevType !== -1 ? (it.Alive === 1 ? '(在线)' : '(离线)') : '')
          map[it[id]] = it // department_id为每个节点的id
        })
        // 生成结果集
        data.forEach(it => {
          const parent = map[it[parentId]] // pid_department_id为父节点的id
          if (parent) {
            if (!Array.isArray(parent.children)) parent.children = []
            parent.children.push(it)
          } else {
            val.push(it)
          }
        })
        return val
      }
    },
    getReplayDate(data) {
      if (data.cameraInfo[this.treeNodeKey]) {
        const url = `${this.layoutConfig.enableHTTPS ? 'https://' : 'http://'}${this.server.api.ip}:8687`
        axios.get(`${url}/ivms/recordquery`, {
          params: {
            chanpubid: data.cameraInfo[this.treeNodeKey],
            starttime: data.start,
            endtime: data.end,
            address: '',
            AuthorizationId: this.authorizationId
          }
        }).then(res => {
          if (res.data.errcode === 0) {
            const _info = this.getNewData(this.layoutSelected)
            const cameraInfo = {
              id: res.data.DeviceID,
              name: res.data.Name,
              list: res.data.RecordList,
              num: res.data.RecordListNum,
              total: res.data.SumNum
            }
            this.setReplayInfo({
              cameraInfo: cameraInfo,
              layoutId: _info.uuid
            })
          }
        })
      }
    },
    // 树节点选择
    currentNodeChange(data) {
      if (this.playMode === 1) {
        this.$refs['tree'].showDateDialog(data)
      } else {
        if (!data.children) {
          if (data.DevType !== -1 && data.Alive === 1) {
            if (!this.isReplace && this.layoutSelected.cameraInfo[this.treeNodeKey]) {
              this.setNextSelected()
            }
            new Promise(resolve => {
              const _info = this.getNewData(this.layoutSelected)
              this.setCameraInfo({
                cameraInfo: data,
                layoutId: _info.uuid
              })
              resolve(_info)
            }).then(_info => {
              this.setNextSelected()
              this.changeIsReplace(false)
            })
          } else {
            this.$message.warning('该摄像头处于离线状态！')
          }
        }
      }
    },
    filterPlay(allList, list) {
      allList.forEach(item => {
        if (list.length) {
          const _list = list.filter(itm => {
            return item[this.treeNodeKey] === itm.cameraInfo[this.treeNodeKey]
          })
          item.isPlay = !!_list.length
          if (_list.length) {
            return false
          } else if (item.children) {
            this.filterPlay(item.children, list)
          }
        } else {
          item.isPlay = false
          if (item.children) {
            this.filterPlay(item.children, list)
          }
        }
      })
    },
    checkChange(data, flag, node) {
      if (!data.children) {
        if (flag) {
          this.addCameraList(data)
        } else {
          this.cutCameraList(data)
        }
      }
    }
  }
}
</script>

<style scoped lang="scss">
.h-layout__main {
  width: 100%;
  height: 100%;
  background: transparent;
  display: flex;
  position: relative;
  overflow: hidden;

  .h-layout__left {
    width: 240px;
    height: 100%;
  }

  .h-layout__right {
    flex: 1;
    height: 100%;
    padding-left: 10px;
  }
}
</style>
